package com.easonji.core.aop;

import java.lang.reflect.Method;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.easonji.common.constant.dictmap.base.AbstractDictMap;
import com.easonji.common.util.HttpUtils;
import com.easonji.common.util.StringUtils;
import com.easonji.core.annotion.BussinessLog;
import com.easonji.core.log.LogManager;
import com.easonji.core.log.LogObjectHolder;
import com.easonji.core.log.factory.LogTaskFactory;
import com.easonji.core.shiro.ShiroUser;
import com.easonji.core.shiro.util.ShiroUtils;
import com.easonji.core.util.ContrastUtils;

/**
 * @ClassName: BussinessLogAop
 * @Description: 业务日志记录AOP
 * @Author: LiuJun
 * @date: 2018/07/18 17:32
 * @Version: 1.0
 * @Copyright: Copyright (c) 2018 - 2019
 */
@Aspect
@Component
public class BussinessLogAop {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Pointcut(value = "@annotation(com.easonji.core.annotion.BussinessLog)")
    public void cutBussinessLog() {
    }

    @Around("cutBussinessLog()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
        try {
            handle(point);
        } catch (Exception e) {
            log.error("日志记录出错!", e);
        }
        // 执行业务
        return point.proceed();
    }

    @SuppressWarnings("rawtypes")
    private void handle(ProceedingJoinPoint point) throws Exception {
        // 获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
        // 如果当前用户未登录，不做日志
        ShiroUser user = ShiroUtils.getUser();
        if (StringUtils.isEmpty(user)) {
            return;
        }
        // 获取拦截方法的参数
        String className = point.getTarget().getClass().getName();
        // 获取操作名称
        BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
        String bussinessName = annotation.value();
        String key = annotation.key();
        Class dictClass = annotation.dict();
        // 如果涉及到修改,比对变化
        String msg = "";
        final String update = "修改";
        final String delete = "删除";
        if (bussinessName.indexOf(update) != -1) {
            Object obj1 = LogObjectHolder.me().get();
            Map<String, String> obj2 = HttpUtils.getRequestParameters();
            msg = ContrastUtils.contrastObj(dictClass, key, obj1, obj2);
        } else {
            Map<String, String> parameters = HttpUtils.getRequestParameters();
            AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
            if (bussinessName.indexOf(delete) != -1) {
                Object obj1 = LogObjectHolder.me().get();
                parameters.put(key, StringUtils.valueOf(obj1));
            }
            msg = ContrastUtils.parseMutiKey(dictMap, key, parameters);
        }
        LogManager.me()
                .executeLog(LogTaskFactory.bussinessLog(user.getUserId(), bussinessName, className, methodName, msg));
    }
}